﻿namespace LastfmNet.Api
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using LastfmNet.Models;

    /// <summary>
    /// Last.fm API venue methods
    /// </summary>
    public class VenueApi
    {
        /// <summary>
        /// Reference to the Lastfm host class
        /// </summary>
        private Lastfm lastfmApi;

        /// <summary>
        /// Initializes a new instance of the VenueApi class.
        /// </summary>
        /// <param name="lastfmApi">Reference to the Lastfm host class</param>
        internal VenueApi(Lastfm lastfmApi)
        {
            this.lastfmApi = lastfmApi;
        }

        /// <summary>
        /// Get a list of upcoming events at this venue. 
        /// This service does not require authentication. 
        /// </summary>
        /// <param name="venue">The id for the venue you would like to fetch event listings for.</param>
        /// <returns>A list of upcoming events at this venue. </returns>
        public IList<LastfmNet.Models.Event> GetEvents(string venue)
        {
            LastfmParameters parameters = new LastfmParameters("venue.getEvents");
            parameters["venue"] = venue.ToString(CultureInfo.InvariantCulture);
            parameters.AddApiKey(this.lastfmApi.Session.ApiKey);
            try
            {
                LastfmResponse result = this.lastfmApi.MakeRequest(parameters);
                return LastfmModelBase.GetList<LastfmNet.Models.Event>(result.MainNode);
            }
            catch (Exception ex)
            {
                throw new LastfmNetException("Unable to get events! (" + ex.Message + ")", ex);
            }
        }

        /// <summary>
        /// Get a paginated list of all the events held at this venue in the past. 
        /// This service does not require authentication. 
        /// </summary>
        /// <param name="venue">The id for the venue you would like to fetch event listings for.</param>
        /// <param name="page">The page of results to return.</param>
        /// <param name="limit">The number of results to fetch per page. Defaults to 50.</param>
        /// <returns>A paginated list of all the events held at this venue in the past. </returns>
        public IList<LastfmNet.Models.Event> GetPastEvents(string venue, int page = 1, int limit = 50)
        {
            LastfmParameters parameters = new LastfmParameters("venue.getPastEvents");
            parameters["page"] = page.ToString(CultureInfo.InvariantCulture);
            parameters["limit"] = limit.ToString(CultureInfo.InvariantCulture);
            parameters["venue"] = venue.ToString(CultureInfo.InvariantCulture);
            parameters.AddApiKey(this.lastfmApi.Session.ApiKey);
            try
            {
                LastfmResponse result = this.lastfmApi.MakeRequest(parameters);
                return LastfmModelBase.GetList<LastfmNet.Models.Event>(result.MainNode);
            }
            catch (Exception ex)
            {
                throw new LastfmNetException("Unable to get past events! (" + ex.Message + ")", ex);
            }
        }

        /// <summary>
        /// Search for a venue by venue name 
        /// This service does not require authentication. 
        /// </summary>
        /// <param name="venue">The venue name you would like to search for.</param>
        /// <param name="page">The results page you would like to fetch</param>
        /// <param name="limit">The number of results to fetch per page. Defaults to 50.</param>
        /// <param name="country">Filter your results by country. Expressed as an ISO 3166-2 code.</param>
        /// <returns>List of venues found</returns>
        public LastfmNet.Models.LastfmOpenSearch<LastfmNet.Models.Venue> Search(string venue, int page = 1, int limit = 50, string country = null)
        {
            LastfmParameters parameters = new LastfmParameters("venue.search");
            parameters["page"] = page.ToString(CultureInfo.InvariantCulture);
            parameters["limit"] = limit.ToString(CultureInfo.InvariantCulture);
            parameters["venue"] = venue.ToString(CultureInfo.InvariantCulture);
            if (country != null)
            {
                parameters["country"] = country;
            }

            parameters.AddApiKey(this.lastfmApi.Session.ApiKey);
            try
            {
                LastfmResponse result = this.lastfmApi.MakeRequest(parameters);
                return new LastfmNet.Models.LastfmOpenSearch<LastfmNet.Models.Venue>(result.MainNode, "venuematches");
            }
            catch (Exception ex)
            {
                throw new LastfmNetException("Unable to search for the venue! (" + ex.Message + ")", ex);
            }
        }
    }
}
